﻿using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;

namespace MongoDB.Interface
{ /// <summary>
  ///数据操作帮助类DBHelper接口
  ///where T: struct  此类型参数必须是值类型，除了Nullable类型的所有类型都可以。where T: class 此类型参数必须是引用类型。
  ///where T: new()	此类型参数必须有一个公有的无参构造函数。当和其它约束参数一起使用时，new()约束必须放在最后。
  ///where T:	此类型参数必须是或者继承自指定的基类。
  ///where T:	此类型参数必须是或者实现了指定的接口。
  ///where T: U 类型参数T必须是或者继承于类型参数。
  /// </summary>
	public interface IDBHelper<T> where T : new()
	{
		/// <summary>
		/// 获取或设置数据库配置
		/// </summary>
		MongoDBConfig DBConfig { get; set; }

		/// <summary>
		/// 获取集合
		/// </summary>
		/// <typeparam name="T">集合对应的类型</typeparam>
		/// <param name="collectionName">集合名称</param>
		/// <returns>集合对象</returns>
		IMongoCollection<T> GetCollection(string collectionName);

		/// <summary>
		/// 根据一个表示来查询单个匹配的数据
		/// </summary>
		/// <typeparam name="T">查询结果的类型</typeparam>
		/// <typeparam name="TField">表示表达式中要获取的对应字段的类型</typeparam>
		/// <param name="fieldExpress">匹配字段的表达式</param>
		/// <param name="value">匹配的值</param>
		/// <returns>查询结果</returns>
		T FindOne<TField>(Expression<Func<T, TField>> fieldExpress, TField value);

		/// <summary>
		/// 根据表达式查询数据
		/// </summary>
		/// <typeparam name="T">查询的数据类型</typeparam>
		/// <param name="express">表达式</param>
		/// <returns>查询结果</returns>
		IList<T> FindDataByExpress(Expression<Func<T, bool>> express);

		/// <summary>
		/// 根据表达式查询排序数据
		/// </summary>
		/// <param name="express"></param>
		/// <param name="orderBy">排序表达式</param>
		/// <param name="sort">1 ASC 2 DESC</param>
		/// <returns></returns>
		IList<T> FindOrderDataByExpress(Expression<Func<T, bool>> express, Expression<Func<T, object>> orderBy, int sort);

		/// <summary>
		/// 获取所有
		/// </summary>
		/// <returns></returns>
		IList<T> FindAll();


		/// <summary>
		/// 查询并生成递归的索引值
		/// </summary>
		/// <typeparam name="TConditionField"></typeparam>
		/// <typeparam name="TSetField"></typeparam>
		/// <param name="conditionExpress"></param>
		/// <param name="conditionValue"></param>
		/// <param name="setExpress"></param>
		/// <param name="setValue"></param>
		/// <returns></returns>
		T InsertNextSequence<TConditionField, TSetField>(Expression<Func<T, TConditionField>> conditionExpress,
							 TConditionField conditionValue, Expression<Func<T, int>> setExpress,
							 Func<T, T> action);

		/// <summary>
		/// 插入一条数据
		/// </summary>
		/// <typeparam name="T">数据类型</typeparam>
		/// <param name="t">数据对象</param>
		/// <returns>数据对象</returns>
		T InsertData(T t);

		/// <summary>
		/// 插入多条数据
		/// </summary>
		/// <typeparam name="T">数据类型</typeparam>
		/// <param name="t">数据对象集合</param>
		/// <returns>数据对象</returns>
		List<T> InsertManyData(List<T> t);


		/// <summary>
		/// 修改多条数据
		/// </summary>
		/// <typeparam name="TConditionField">条件类型</typeparam>
		/// <typeparam name="TSetField">更新类型</typeparam>
		/// <param name="conditionExpress">条件表达式</param>
		/// <param name="conditionValue">条件表达式值</param>
		/// <param name="setExpress">更新字段表达式</param>
		/// <param name="setValue">更新字段值</param>
		/// <returns></returns>
		long UpdateMany<TConditionField, TSetField>(Expression<Func<T, TConditionField>> conditionExpress,
													TConditionField conditionValue,
													Expression<Func<T, TSetField>> setExpress,
													TSetField setValue);


		/// <summary>
		/// 删除单条数据
		/// </summary>
		/// <typeparam name="T">数据类型</typeparam>
		/// <param name="fieldExpress">匹配数据的表达式</param>        
		/// <returns>执行结果</returns>
		bool DeleteOne(Expression<Func<T, bool>> fieldExpress);

		/// <summary>
		/// 删除多条数据
		/// </summary>
		/// <typeparam name="T">数据类型</typeparam>
		/// <param name="fieldExpress">匹配字段的表达式</param>        
		/// <returns>执行结果</returns>
		long DeleteMany(Expression<Func<T, bool>> fieldExpress);
	}
}
